﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;


namespace Autorun
{
	public partial class ScheduleDialog : Form
	{

		#region "Members"
		private ServerManagement _proxy;
		private ScheduleItem _item;
		#endregion

		#region "Constructors and Form's Events Handlers"
		public ScheduleDialog()
		{
			InitializeComponent();
		}
		#endregion

		#region "Procedures"
		public void SetData(ServerManagement proxy, TaskConfigurationItem task)
		{
			_proxy = proxy;
			LoadData();

			cbTask.SelectedValue = task.Id;
		}

		public void SetData(ServerManagement proxy, int recordId)
		{
			_proxy = proxy;
			DayRange dr;

			LoadData();

			if (recordId == 0)
				_item = null;
			else
			{
				_item = _proxy.Scheduler.GetScheduleInformation(recordId);

				// === Related task item =============================================
				cbTask.SelectedValue = _item.TaskId;

				// === Schedule type =================================================
				((RadioButton)grpSchedule.Controls[string.Format("opt{0}", _item.Types.ToString())]).Checked = true;

				// === Common information ============================================
				calStart.Value = _item.StartDateTime.Date;
				txtStart.Text = _item.StartDateTime.ToString("HH:mm");
				if (_item.FinishDate.Date == DateTime.MaxValue.Date)
					chkFinish.Checked = false;
				else
				{
					chkFinish.Checked = true;
					calFinish.Value = _item.FinishDate.Date;
				}
				if (_item.RepeatEvery == TimeSpan.Zero)
					chkRepeat.Checked = false;
				else
				{
					chkRepeat.Checked = true;
					txtRepeat.Text = _item.RepeatEvery.ToString();
					txtFinish.Text = _item.FinishTime.TimeOfDay.ToString();
				}

				// === Specific information ==========================================
				switch (_item.Types)
				{
					case ScheduleTypes.Weekly:
						chkMo.Checked = ((_item.RunOnWeekDays & ScheduleWeekDays.Monday) == ScheduleWeekDays.Monday);
						chkTu.Checked = ((_item.RunOnWeekDays & ScheduleWeekDays.Tuesday) == ScheduleWeekDays.Tuesday);
						chkWe.Checked = ((_item.RunOnWeekDays & ScheduleWeekDays.Wednesday) == ScheduleWeekDays.Wednesday);
						chkTh.Checked = ((_item.RunOnWeekDays & ScheduleWeekDays.Thursday) == ScheduleWeekDays.Thursday);
						chkFr.Checked = ((_item.RunOnWeekDays & ScheduleWeekDays.Friday) == ScheduleWeekDays.Friday);
						chkSa.Checked = ((_item.RunOnWeekDays & ScheduleWeekDays.Saturday) == ScheduleWeekDays.Saturday);
						chkSu.Checked = ((_item.RunOnWeekDays & ScheduleWeekDays.Sunday) == ScheduleWeekDays.Sunday);
						break;
					case ScheduleTypes.Monthly:
						chkJan.Checked = ((_item.RunOnMonths & ScheduleMonths.Jan) == ScheduleMonths.Jan);
						chkFeb.Checked = ((_item.RunOnMonths & ScheduleMonths.Feb) == ScheduleMonths.Feb);
						chkMar.Checked = ((_item.RunOnMonths & ScheduleMonths.Mar) == ScheduleMonths.Mar);
						chkApr.Checked = ((_item.RunOnMonths & ScheduleMonths.Apr) == ScheduleMonths.Apr);
						chkMay.Checked = ((_item.RunOnMonths & ScheduleMonths.May) == ScheduleMonths.May);
						chkJun.Checked = ((_item.RunOnMonths & ScheduleMonths.Jun) == ScheduleMonths.Jun);
						chkJul.Checked = ((_item.RunOnMonths & ScheduleMonths.Jul) == ScheduleMonths.Jul);
						chkAug.Checked = ((_item.RunOnMonths & ScheduleMonths.Aug) == ScheduleMonths.Aug);
						chkSep.Checked = ((_item.RunOnMonths & ScheduleMonths.Sep) == ScheduleMonths.Sep);
						chkOct.Checked = ((_item.RunOnMonths & ScheduleMonths.Oct) == ScheduleMonths.Oct);
						chkNov.Checked = ((_item.RunOnMonths & ScheduleMonths.Nov) == ScheduleMonths.Nov);
						chkDec.Checked = ((_item.RunOnMonths & ScheduleMonths.Dec) == ScheduleMonths.Dec);

						dr = new DayRange(_item.RunOnDays);
						txtDays.Text = dr.ToString();
						if (txtDays.Text.Length != 0)
							optDays.Checked = true;
						else
							optOn.Checked = true;

						break;
				}
			}
		}

		private void LoadData()
		{
			LoadRecurrence();
			LoadWeekDays();
			LoadTasks();
		}

		private void LoadWeekDays()
		{
			DataTable dt;

			dt = new DataTable();
			dt.Columns.Add("ValueMember");
			dt.Columns.Add("DisplayMember");

			foreach (string item in Enum.GetNames(typeof(ScheduleWeekDays)))
				if ((int)Enum.Parse(typeof(ScheduleWeekDays), item) != 0)
					dt.Rows.Add(Enum.Parse(typeof(ScheduleWeekDays), item), item);

			cbOnWeekDay.DisplayMember = "DisplayMember";
			cbOnWeekDay.ValueMember = "ValueMember";
			cbOnWeekDay.DataSource = dt;
		}

		private void LoadRecurrence()
		{
			DataTable dt;

			dt = new DataTable();
			dt.Columns.Add("ValueMember");
			dt.Columns.Add("DisplayMember");

			foreach (string item in Enum.GetNames(typeof(ScheduleRunOnDayOccurences)))
				if ((int)Enum.Parse(typeof(ScheduleRunOnDayOccurences), item) != 0)
					dt.Rows.Add(Enum.Parse(typeof(ScheduleRunOnDayOccurences), item), item);

			cbOnRecurrence.DisplayMember = "DisplayMember";
			cbOnRecurrence.ValueMember = "ValueMember";
			cbOnRecurrence.DataSource = dt;
		}

		private void LoadTasks()
		{
			DataTable dt;

			dt = new DataTable();
			dt.Columns.Add("ValueMember");
			dt.Columns.Add("DisplayMember");

			foreach (TaskConfigurationItem item in _proxy.Configuration.Tasks.Items)
				dt.Rows.Add(item.Id, item.Caption);

			cbTask.DisplayMember = "DisplayMember";
			cbTask.ValueMember = "ValueMember";
			cbTask.DataSource = dt;
		}
		#endregion

		#region "Controls Events Handlers"
		private void ScheduleType_CheckedChanged(object sender, EventArgs e)
		{
			ScheduleTypes type;

			type = (ScheduleTypes)Enum.Parse(typeof(ScheduleTypes), ((RadioButton)sender).Name.Substring(3), true);

			switch (type)
			{
				case ScheduleTypes.Inactive:
					grpCommon.Enabled = false;
					grpDaily.Visible = false;
					grpMonthly.Visible = false;
					break;
				case ScheduleTypes.Startup:
				case ScheduleTypes.Shutdown:
					grpCommon.Enabled = true;
					txtStart.Enabled = false;
					txtFinish.Enabled = false;
					chkRepeat.Enabled = false;
					txtRepeat.Enabled = false;
					lblRepeat.Enabled = false;
					grpDaily.Visible = false;
					grpMonthly.Visible = false;
					break;
				case ScheduleTypes.Daily:
					grpCommon.Enabled = true;
					txtStart.Enabled = true;
					txtFinish.Enabled = chkRepeat.Checked;
					chkRepeat.Enabled = true;
					txtRepeat.Enabled = chkRepeat.Checked;
					lblRepeat.Enabled = chkRepeat.Checked;
					grpDaily.Visible = false;
					grpMonthly.Visible = false;
					break;
				case ScheduleTypes.Weekly:
					grpCommon.Enabled = true;
					txtStart.Enabled = true;
					txtFinish.Enabled = chkRepeat.Checked;
					chkRepeat.Enabled = true;
					txtRepeat.Enabled = chkRepeat.Checked;
					lblRepeat.Enabled = chkRepeat.Checked;
					grpDaily.Visible = true;
					grpMonthly.Visible = false;
					break;
				case ScheduleTypes.Monthly:
					grpCommon.Enabled = true;
					txtStart.Enabled = true;
					txtFinish.Enabled = chkRepeat.Checked;
					chkRepeat.Enabled = true;
					txtRepeat.Enabled = chkRepeat.Checked;
					lblRepeat.Enabled = chkRepeat.Checked;
					grpDaily.Visible = false;
					grpMonthly.Visible = true;
					break;
				default:
					break;
			}
		}

		private void chkFinish_CheckedChanged(object sender, EventArgs e)
		{
			calFinish.Enabled = chkFinish.Checked;
		}

		private void chkRepeat_CheckedChanged(object sender, EventArgs e)
		{
			txtRepeat.Enabled = chkRepeat.Checked;
			lblRepeat.Enabled = chkRepeat.Checked;
			txtFinish.Enabled = chkRepeat.Checked;
		}

		private void optDays_CheckedChanged(object sender, EventArgs e)
		{
			txtDays.Visible = optDays.Checked;
			cbOnRecurrence.Visible = optOn.Checked;
			cbOnWeekDay.Visible = optOn.Checked;
		}

		private void btOK_Click(object sender, EventArgs e)
		{
			ScheduleTypes type;
			ScheduleWeekDays runOnWeekdays;
			ScheduleMonths runOnMonths;
			int runOnDays;
			ScheduleRunOnDayOccurences runOnDayOccurence;
			int taskId;
			DateTime startDateTime;
			DateTime finishDate;
			DateTime finishTime;
			TimeSpan repeat;
			DayRange dr;

			// =====================================================================
			// === Validate data                                                 ===
			// =====================================================================
			// === Common data =====================================================
			if (cbTask.SelectedIndex == -1)
			{
				MessageBox.Show("No task selected", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}

			if ((chkFinish.Checked == true) && (calFinish.Value < calStart.Value))
			{
				MessageBox.Show("The finish date should be greater than the start date", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}

			///TODO: finalize validations

			// =====================================================================
			// === Prepare paramters                                             ===
			// =====================================================================
			if (optInactive.Checked == true)
				type = ScheduleTypes.Inactive;
			else if (optStartup.Checked == true)
				type = ScheduleTypes.Startup;
			else if (optShutdown.Checked == true)
				type = ScheduleTypes.Shutdown;
			else if (optDaily.Checked == true)
				type = ScheduleTypes.Daily;
			else if (optWeekly.Checked == true)
				type = ScheduleTypes.Weekly;
			else if (optMonthly.Checked == true)
				type = ScheduleTypes.Monthly;
			else
				type = ScheduleTypes.Inactive;

			runOnWeekdays = ScheduleWeekDays.None;
			if ((type & ScheduleTypes.Weekly) == ScheduleTypes.Weekly)
			{
				if (chkMo.Checked == true) runOnWeekdays |= ScheduleWeekDays.Monday;
				if (chkTu.Checked == true) runOnWeekdays |= ScheduleWeekDays.Tuesday;
				if (chkWe.Checked == true) runOnWeekdays |= ScheduleWeekDays.Wednesday;
				if (chkTh.Checked == true) runOnWeekdays |= ScheduleWeekDays.Thursday;
				if (chkFr.Checked == true) runOnWeekdays |= ScheduleWeekDays.Friday;
				if (chkSa.Checked == true) runOnWeekdays |= ScheduleWeekDays.Saturday;
				if (chkSu.Checked == true) runOnWeekdays |= ScheduleWeekDays.Sunday;
			}

			runOnMonths = ScheduleMonths.None;
			runOnDays = 0;
			runOnDayOccurence = ScheduleRunOnDayOccurences.None;
			if ((type & ScheduleTypes.Monthly) == ScheduleTypes.Monthly)
			{
				if (chkJan.Checked == true) runOnMonths |= ScheduleMonths.Jan;
				if (chkFeb.Checked == true) runOnMonths |= ScheduleMonths.Feb;
				if (chkMar.Checked == true) runOnMonths |= ScheduleMonths.Mar;
				if (chkApr.Checked == true) runOnMonths |= ScheduleMonths.Apr;
				if (chkMay.Checked == true) runOnMonths |= ScheduleMonths.May;
				if (chkJun.Checked == true) runOnMonths |= ScheduleMonths.Jun;
				if (chkJul.Checked == true) runOnMonths |= ScheduleMonths.Jul;
				if (chkAug.Checked == true) runOnMonths |= ScheduleMonths.Aug;
				if (chkSep.Checked == true) runOnMonths |= ScheduleMonths.Sep;
				if (chkOct.Checked == true) runOnMonths |= ScheduleMonths.Oct;
				if (chkNov.Checked == true) runOnMonths |= ScheduleMonths.Nov;
				if (chkDec.Checked == true) runOnMonths |= ScheduleMonths.Dec;
				///TODO: finalize Monthly Scheduling
				if (optDays.Checked == true)
				{
					if (DayRange.TryParse(txtDays.Text, out dr) == false)
					{
						MessageBox.Show("The day range is not valid", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
						return;
					}
					else
						runOnDays = (int)dr.RawValue;
				}
				if (optOn.Checked == true)
				{
				}
			}

			taskId = int.Parse(cbTask.SelectedValue.ToString());

			startDateTime = new DateTime(calStart.Value.Year, calStart.Value.Month, calStart.Value.Day, int.Parse(txtStart.Text.Substring(0, 2)), int.Parse(txtStart.Text.Substring(3, 2)), 0);

			if (chkFinish.Checked == false)
				finishDate = DateTime.MaxValue;
			else
				finishDate = calFinish.Value;

			if (chkRepeat.Checked == true)
			{
				repeat = new TimeSpan(0, int.Parse(txtRepeat.Text.Substring(0, 2)), int.Parse(txtRepeat.Text.Substring(3, 2)), 0);
				finishTime = new DateTime(2030, DateTime.MaxValue.Month, DateTime.MaxValue.Day, int.Parse(txtFinish.Text.Substring(0, 2)), int.Parse(txtFinish.Text.Substring(3, 2)), 0);
			}
			else
			{
				repeat = new TimeSpan(0);
				finishTime = DateTime.MaxValue;
			}

			if (_item == null)
				_proxy.Scheduler.Add(
						taskId,
						type,
						calStart.Value,
						startDateTime,
						finishDate,
						finishTime,
						repeat,
						runOnWeekdays,
						runOnMonths,
						runOnDays,
						runOnDayOccurence);
			else
			{
				_item.TaskId = taskId;
				_item.Types = type;
				_item.StartDateTime = startDateTime;
				_item.FinishDate = finishDate;
				_item.FinishTime = finishTime;
				_item.RepeatEvery = repeat;
				_item.RunOnWeekDays = runOnWeekdays;
				_item.RunOnMonths = runOnMonths;
				_item.RunOnDays = runOnDays;
				_item.RunOnDayOccurences = runOnDayOccurence;

				_item.Update();
			}

			DialogResult = DialogResult.OK;
		}
		#endregion
	}
}
